<?php
// $Id$
//

/**
 *
 * @author donny
 * @property ADOConnection $adodb
 */
class Rememberme_cookies_model extends MY_Model {

  var $cookie_name   = 'TEFList_rememberme';
  var $cookie_domain = '';
  var $cookie_path   = '/';
  var $encryption_key = 'TEFList';

  function Rememberme_cookies_model()
  {
    
    // Call the Model constructor
    parent::MY_Model();    
    $this->table = 'rememberme_cookies';
  }

  /**
   *
   * @param $user_id integer
   * @param $series string
   * @param $token string
   * @return TRUE
   */
  function store_cookies($user_id, $series, $token)
  {
    $cookie_data['user_id'] = $user_id;
    $cookie_data['series']  = $series;
    $cookie_data['token']   = $token;
    $cookie_data = $this->session->_serialize($cookie_data);
    $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);

    // Set the cookie
    setcookie(
          $this->cookie_name,
          $cookie_data,
          (60*60*24*365*2) + time(),
          $this->cookie_path,
          $this->cookie_domain,
          0
        );
    return TRUE;
  }

  /**
   *
   * @return $cookie_data or FALSE
   */
  function read_cookies()
  {
    // Fetch the cookie
    $cookie_data = $this->input->cookie($this->cookie_name);

    // No cookie?  Goodbye cruel world!...
    if ($cookie_data === FALSE)
    {
      log_message('debug', 'A rememberme session cookie was not found.');
      return FALSE;
    }

    // Decrypt the cookie data
    $hash  = substr($cookie_data, strlen($cookie_data)-32); // get last 32 chars
    $cookie_data = substr($cookie_data, 0, strlen($cookie_data)-32);

    // Does the md5 hash match?  This is to prevent manipulation of session data in userspace
    if ($hash !==  md5($cookie_data.$this->encryption_key))
    {
      log_message('error', 'The rememberme session cookie data did not match what was expected. This could be a possible hacking attempt.');
      $this->sess_destroy();
      return FALSE;
    }

    // Unserialize the session array
    $cookie_data = $this->session->_unserialize($cookie_data);

    // Session is valid!
    return $cookie_data;
  }

  /**
   *
   * @return void
   */
  function sess_destroy()
  {
    // Kill the cookie
    setcookie(
          $this->cookie_name,
          addslashes(serialize(array())),
          (time() - 31500000),
          $this->cookie_path,
          $this->cookie_domain,
          0
        );
  }

  /**
   * (non-PHPdoc)
   * @see system/application/libraries/MY_Model#get_detail($id)
   */
  function get_detail($user_id, $series)
  {
    
    $user_id = intval($user_id);
    $sql = "SELECT * FROM {$this->table} WHERE user_id=? AND series=? ";
    $rs = $this->adodb->Execute($sql, array($user_id, $series));
    $this->db->last_query();
    if (!$rs)
    {
      $this->set_error($this->adodb->ErrorMsg());
      return FALSE;
    }
    if ($rs->RecordCount() > 0)
    {
      return $rs->FetchRow();
    }
    return FALSE;
  }

  /**
   *
   * @param $user_id integer
   * @return boolean
   */
  function check($user_id, $create_new = FALSE)
  {
    $cookie_data = $this->read_cookies();
    if ($cookie_data AND is_array($cookie_data) AND $cookie_data['user_id'] == $user_id)
    {
      $series = $cookie_data['series'];
      $token = $cookie_data['token'];
      //get data from db
      
      $result = $this->get_detail($user_id, $series);
      //token found, do checking
      if ($result AND is_array($result))
      {
        //token valid
        if ($result['token'] == $token)
        {
          //generate new token
          $new_token = md5(uniqid(mt_rand(), true));
          $save = $this->save($user_id, $series, $new_token);
          if ($save)
          {
            $this->store_cookies($user_id, $series, $new_token);
            return TRUE;
          }
        }
        //else, token invalid, identity theft assumed, delete all stored session for the user, set error message
        else
        {
          $delete = $this->delete_by_user($user_id);
          if (empty($this->error_msg)) // prevent double message
          {
            //set identity theft message
            $this->set_error("We have detected identity theft. All your remembered session have been deleted! Please re-login to access your account!");
          }
          return FALSE;
        }
      }
    }
    if ($create_new)
    {
      //no cookie, create new one
      $series = md5(uniqid(mt_rand(), true));
      $token  = md5(uniqid(mt_rand(), true));
      $save = $this->save($user_id, $series, $token);
      if ($save)
      {
        $this->store_cookies($user_id, $series, $token);
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   *
   * @param $user_id integer
   * @param $series string
   * @param $token string
   * @return boolean
   */
  function save($user_id, $series, $token)
  {
    $result = TRUE;
    $data['user_id']  = $user_id;
    $data['series']   = $series;
    $data['token']    = $token;
    $data['modified_time'] = time();
    //get data from db
    $detail = $this->get_detail($user_id, $series);
    if (!$detail OR !is_array($detail))
    {
      //insert
      $result = $this->adodb->AutoExecute($this->table, $data, 'INSERT');
    }
    else
    {
      //update
      $user_id = intval($user_id);
      $series = $this->adodb->qstr($series, get_magic_quotes_gpc());
      $result = $this->adodb->AutoExecute($this->table, $data, 'UPDATE', "user_id=$user_id AND series=$series");
    }
    return $result;
  }

  /**
   *
   * @param $user_id integer
   * @return boolean
   */
  function delete_by_user($user_id)
  {
    $user_id = intval($user_id);
    $sql = "DELETE FROM {$this->table} WHERE user_id=? ";
    $result = $this->adodb->Execute($sql, array($user_id));
    if (!$result)
    {
      $this->set_error($this->adodb->ErrorMsg());
      return FALSE;
    }
    $this->sess_destroy();
    return $result;
  }

  /**
   * (non-PHPdoc)
   * @see system/application/libraries/MY_Model#delete($id)
   */
  function delete($user_id, $series)
  {
    $user_id = intval($user_id);
    $sql = "DELETE FROM {$this->table} WHERE user_id=? AND series=? ";
    $result = $this->adodb->Execute($sql, array($user_id, $series));
    if (!$result)
    {
      $this->set_error($this->adodb->ErrorMsg());
      return FALSE;
    }
    $this->sess_destroy();
    return $result;
  }

}

/* End of file rememberme_cookies_model.php */
/* Location: ./system/application/models/rememberme_cookies_model.php */